template<typename T>
void RationalNumberTools::stringToRational(const std::string& sValue, boost::rational<T>& nOutputValue, bool bReductionByGCD) {
	bool bSign;
	std::string sFirstValue;
	std::string sSecondValue;
	std::string sExponent;
	bool bExponentSign;

	parseStringRationalFormat(sValue, bSign, sFirstValue, sSecondValue, sExponent, bExponentSign);

	T nExponentValue = boost::lexical_cast<T>(sExponent);

	std::string sNumerator;
	sNumerator.reserve(16);
	std::string sDenominator;
	sDenominator.reserve(16);

	sNumerator = (bSign ? "":"-")+sFirstValue; //+sSecondValue;
	sDenominator = "1";

	bool bStillZero = true;
	for(unsigned int i = sSecondValue.size(); i > 0 ;  i--) {
		if(sSecondValue[i-1]=='0' && bStillZero)
			continue;
		bStillZero = false;
		sDenominator+="0";
	}

	for(unsigned int i = 0; i < sDenominator.size()-1 ;  i++) {
		sNumerator+=sSecondValue[i];
	}

	if(nExponentValue!=0) {
		if(bExponentSign) {
			for(T i = 0; i < nExponentValue; i++) {
				if(sDenominator.size() > 1)
					boost::algorithm::erase_tail(sDenominator, 1);
				else
					sNumerator+="0";
			}
		}
		else {
			for(T i = 0; i < nExponentValue; i++) {
				sDenominator+="0";
			}
		}
	}

	T nNumerator = boost::lexical_cast<T>(sNumerator);
	T nDenominator = boost::lexical_cast<T>(sDenominator);
	if(bReductionByGCD) {
		T nGCD = boost::math::gcd(nNumerator,nDenominator);
		nNumerator = nNumerator / nGCD;
		nDenominator = nDenominator / nGCD;
	}
	nOutputValue.assign(nNumerator, nDenominator);
}

template<typename T>
void RationalNumberTools::rationalToString(const boost::rational<T>& nValue, std::string& sOutputValue, const unsigned int nMaxPrecision) {
	sOutputValue.clear();
	sOutputValue.reserve ( nMaxPrecision + 16 );

	unsigned int nIdx = 0;
	bool bHasDot = false;

	T nValDiv = nValue.numerator() / nValue.denominator();
	T nValRemain = nValue.numerator() % nValue.denominator();

	while(nIdx < nMaxPrecision) {

		sOutputValue+=boost::lexical_cast<std::string>(nValDiv);
		if(nValRemain!=0) {
			nIdx++;
			if(!bHasDot) {
				sOutputValue+=".";
				bHasDot = true;
			}
			T nMulRemain = nValRemain * 10 ;
			nValDiv =   nMulRemain / nValue.denominator();
			nValRemain = nMulRemain % nValue.denominator();
		}
		else
			break;
	}
}
